home *** CD-ROM | disk | FTP | other *** search
- #ifndef _CVECTOR_H
- #define _CVECTOR_H
-
- #include <stream.h>
- #include <math.h>
- #include "vector_names.h"
-
- // This is a template for a Cartesian vector class.
- // The usual operators are supplied.
-
- #define CartesianVectorDeclare(T) \
- class CVec(T) { \
- public: \
- static errorHandler error; \
- static void badvec(int, const char *); \
- static errorHandler setErrorHandler(errorHandler); \
- \
- T &operator[](int i) { return x[i]; } \
- T operator()(int i) const { return x[i]; } \
- operator T*() { return x; } \
- \
- CVec(T)() {} \
- \
- CVec(T)(T xval, T yval, T zval) { \
- x[0] = xval; x[1] = yval; x[2] = zval; \
- } \
- \
- CVec(T)(const CVec(T) &v) { \
- x[0] = v(0); x[1] = v(1); x[2] = v(2); \
- } \
- \
- T magnitude() const { \
- return sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]); \
- } \
- \
- CVec(T) &normalize(); \
- \
- CVec(T) &operator+=(const CVec(T) &v) { \
- x[0] += v(0); \
- x[1] += v(1); \
- x[2] += v(2); \
- return *this; \
- } \
- \
- CVec(T) &operator-=(const CVec(T) &v) { \
- x[0] -= v(0); \
- x[1] -= v(1); \
- x[2] -= v(2); \
- return *this; \
- } \
- \
- CVec(T) &operator*=(T s) { \
- x[0] *= s; \
- x[1] *= s; \
- x[2] *= s; \
- return *this; \
- } \
- \
- CVec(T) &operator/=(T s) { \
- T recip = 1.0 / s; \
- x[0] *= recip; \
- x[1] *= recip; \
- x[2] *= recip; \
- return *this; \
- } \
- \
- protected: \
- T x[3]; \
- }; \
- \
- /* -V */ \
- inline CVec(T) operator-(const CVec(T) &v) \
- { \
- return CVec(T)(-v(0), -v(1), -v(2)); \
- } \
- \
- /* s * V */ \
- inline CVec(T) operator*(T s, const CVec(T) &v) \
- { \
- return CVec(T)(s * v(0), s * v(1), s * v(2)); \
- } \
- \
- /* V * s */ \
- inline CVec(T) operator*(const CVec(T) &v, T s) { \
- return s * v; \
- } \
- \
- /* V / s */ \
- inline CVec(T) operator/(const CVec(T) &v, T s) \
- { \
- T recip = 1.0 / s; \
- return CVec(T)(v(0) * recip, v(1) * recip, v(2) * recip); \
- } \
- \
- /* V + V */ \
- inline CVec(T) operator+(const CVec(T) &a, const CVec(T) &b) \
- { \
- return CVec(T)(a(0) + b(0), a(1) + b(1), a(2) + b(2)); \
- } \
- \
- /* V - V */ \
- inline CVec(T) operator-(const CVec(T) &a, const CVec(T) &b) \
- { \
- return CVec(T)(a(0) - b(0), a(1) - b(1), a(2) - b(2)); \
- } \
- \
- /* V cross V */ \
- inline CVec(T) operator^(const CVec(T) &a, const CVec(T) &b) \
- { \
- return CVec(T)(a(1) * b(2) - a(2) * b(1), \
- a(2) * b(0) - a(0) * b(2), \
- a(0) * b(1) - a(1) * b(0)); \
- } \
- \
- /* V dot V */ \
- inline T operator*(const CVec(T) &a, const CVec(T) &b) \
- { \
- return a(0) * b(0) + a(1) * b(1) + a(2) * b(2); \
- } \
- \
- /* V == V (no fuzz for comparison) */ \
- inline int operator==(const CVec(T) &a, const CVec(T) &b) \
- { \
- return (a(0) == b(0)) && (a(1) == b(1)) && (a(2) == b(2)); \
- } \
- \
- /* V != V (no fuzz for comparison) */ \
- inline int operator!=(const CVec(T) &a, const CVec(T) &b) { \
- return !(a == b); \
- } \
- \
- ostream &operator<<(ostream &o, const CVec(T) &v);
-
- #define CartesianVectorImplement(T) \
- \
- errorHandler CVec(T)::error = &CVec(T)::badvec; \
- \
- void CVec(T)::badvec(int code, const char *msg) { \
- cerr << "CVec(T): error " << code << ": " \
- << msg << endl; \
- } \
- \
- errorHandler CVec(T)::setErrorHandler(errorHandler e) { \
- errorHandler old = CVec(T)::error; \
- CVec(T)::error = e; \
- return old; \
- } \
- \
- CVec(T) &CVec(T)::normalize() { \
- T mag = this->magnitude(); \
- \
- if (mag != 0.0) { \
- mag = 1.0 / mag; \
- x[0] *= mag; \
- x[1] *= mag; \
- x[2] *= mag; \
- } else { \
- (*error)(0, "magnitude=0 in normalize"); \
- } \
- \
- return *this; \
- } \
- \
- ostream &operator<<(ostream &o, const CVec(T) &v) { \
- return o << "( " << v(0) << ' ' \
- << v(1) << ' ' << v(2) << " )"; \
- }
-
- CartesianVectorDeclare(float);
-
- typedef CVec(float) Vector;
-
- #endif /*_CVECTOR_H*/
-